package com.plm.blogs.controller;

import com.alibaba.fastjson.JSON;
import com.plm.blogs.entity.User;
import com.plm.blogs.service.UserService;
import com.plm.blogs.utils.EmailTool;
import com.plm.blogs.utils.Encrypt;
import com.plm.blogs.utils.ResultMsg;
import com.plm.blogs.utils.SessionTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Limi
 * @create 2019-01-09 23:40
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/login")
    public ModelAndView login(){
        ModelAndView mv = new ModelAndView("user/login");
        return mv;
    }

    @GetMapping("/reg")
    public ModelAndView toReg(){
        ModelAndView mv = new ModelAndView("user/reg");
        return mv;
    }

    @GetMapping("/forget")
    public ModelAndView forget(Model model){
        ModelAndView mv = new ModelAndView("user/forget");
        return mv;
    }

    @PostMapping("/register")
    public ResultMsg register(@RequestParam Map<String, Object> params){
        User user = JSON.parseObject(JSON.toJSONString(params), User.class);
        user.setId(UUID.randomUUID().toString());
        //用手机号做盐
        user.setPassword(Encrypt.encrypt(user.getPassword(), user.getPhone()));
        user.setStatus("1");//0：被锁定；1正常
        user.setActivate("0");//邮箱默认为未激活
        user.setAvatar("/static/images/avatar/13.jpg");//设置默认头像
        user.setCreateTime(new Date());
        try {
            userService.add(user);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("注册失败，请联系管理员");
        }
        return ResultMsg.ok("注册成功，去登入吧");
    }

    @PostMapping("/login_action")
    public ResultMsg loginAction(@RequestParam Map<String, Object> params){
        Subject subject = SecurityUtils.getSubject();

        String imagecode = (String) params.get("imagecode");
        if (authImageCode(imagecode.toLowerCase())) {
            return ResultMsg.error("图形验证不匹配");
        }

        String phone = (String) params.get("phone");
        String email = (String) params.get("email");
        if (!"".equals(email)) {
            User user = userService.findByEmail(email);
            //如果邮箱没有激活，不允许用邮箱登录
            if ("0".equals(user.getActivate())) {
                return ResultMsg.error("邮箱未激活，不允许作为账号登录");
            }
        }
        String password = (String) params.get("password");
        String username = !"".equals(phone) ? phone : email;

        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            log.info(e.getMessage());
            return ResultMsg.error(e.getMessage());
        } catch (IncorrectCredentialsException e) {
            log.info(e.getMessage());
            return ResultMsg.error(e.getMessage());
        } catch (LockedAccountException e) {
            log.info(e.getMessage());
            return ResultMsg.error(e.getMessage());
        } catch (AuthenticationException e) {
            log.info(e.getMessage());
            return ResultMsg.error("认证失败！");
        }
        return ResultMsg.okGo("/");
    }

    private boolean authImageCode(String imagecode) {
        String captcha = (String) SessionTool.getSession().getAttribute("captcha");
        if (!captcha.equals(imagecode)) {
            return true;
        }
        return false;
    }

    @GetMapping("/home")
    public ModelAndView home(Model model){
        ModelAndView mv = new ModelAndView("user/home");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        return mv;
    }

    @GetMapping("/set/{title}")
    public ModelAndView set(Model model, @PathVariable("title") String title){
        ModelAndView mv = new ModelAndView("user/set");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        if (null != title && !"".equals(title)) {
            model.addAttribute("title", title.trim());
        } else {
            model.addAttribute("title", "info");
        }
        return mv;
    }

    @GetMapping("/activate")
    public ModelAndView activate(Model model){
        ModelAndView mv = new ModelAndView("user/activate");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        return mv;
    }

    @PostMapping("set_avatar")
    public ResultMsg setAvatar(@RequestParam Map<String, Object> params){
        String avatar = (String) params.get("avatar");
        User user = SessionTool.getUser();
        user.setAvatar(avatar);
        try {
            userService.updateById(user);
            SessionTool.setUser(user);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("系统出错，请联系管理员");
        }
        return ResultMsg.ok("头像设置成功");
    }

    @PostMapping("/reset_pass")
    public ResultMsg resetPassword(@RequestParam Map<String, Object> params){
        String imagecode = (String) params.get("imagecode");
        String email = (String) params.get("email");
        if (authImageCode(imagecode)) {
            return ResultMsg.error("图形验证不匹配");
        }
        //随机生成6位数字密码
        String newPssword = Encrypt.randomPass();

        User user = null;
        try {
            user = userService.findByEmail(email);
            //MD5带盐加密
            String md5Password = Encrypt.encrypt(newPssword, user.getPhone());
            user.setPassword(md5Password);
            userService.updateById(user);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("系统出错，请联系管理员");
        }

        //将随机生成的密码通过邮件通知用户
        boolean isSuccess = EmailTool.sendEmail(email, newPssword, "0");
        if (!isSuccess) {
            return ResultMsg.error("网络出错，请稍后再试");
        }

        if (user != null) {
            SessionTool.setUser(user);
        }

        return ResultMsg.ok("密码已发送到您邮箱，请登入您的邮箱查看密码");
    }

    @PostMapping("update_pass")
    public ResultMsg updatePassword(@RequestParam Map<String, Object> params){
        String oldPass = (String) params.get("nowpass");
        User user = SessionTool.getUser();
        if (!user.getPassword().equals(Encrypt.encrypt(oldPass, user.getPhone()))) {
            return ResultMsg.error("原密码有误");
        }
        String newPass = (String) params.get("pass");
        String newPassSlat = Encrypt.encrypt(newPass, user.getPhone());
        try {
            user.setPassword(newPassSlat);
            userService.updateById(user);
            SessionTool.setUser(user);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("系统出错，请联系管理员");
        }
        return ResultMsg.ok("密码修改成功");
    }

    @PostMapping("/setinfo")
    public ResultMsg setinfo(@RequestParam Map<String, Object> params){
        String imagecode = (String) params.get("imagecode");
        String captcha = (String) SessionTool.getSession().getAttribute("captcha");
        if (!imagecode.equals(captcha)) {
            return ResultMsg.error("图形验证不匹配");
        }
        try {
            User user = JSON.parseObject(JSON.toJSONString(params), User.class);
            User userOld = userService.findById(user.getId());
            //更新数据
            //邮箱不一样才修改
            if (!user.getEmail().equals(userOld.getEmail())) {
                userOld.setActivate("0");
                userOld.setEmail(user.getEmail());
            }
            userOld.setUsername(user.getUsername());
            userOld.setGender(user.getGender());
            userOld.setCity(user.getCity());
            userOld.setSign(user.getSign());
            //更新到数据库
            userService.updateById(userOld);
            //更新到session
            SessionTool.setUser(userOld);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("系统出错，请联系管理员");
        }
        return ResultMsg.ok("更新成功");
    }

    @GetMapping("/center")
    public ModelAndView center(Model model){
        ModelAndView mv = new ModelAndView("user/center");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        return mv;
    }

    @GetMapping("/post")
    public ModelAndView post(Model model){
        ModelAndView mv = new ModelAndView("user/post");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        return mv;
    }

    @GetMapping("/message")
    public ModelAndView message(Model model){
        ModelAndView mv = new ModelAndView("user/message");
        User user = SessionTool.getUser();
        model.addAttribute("user", user);
        return mv;
    }

    @PostMapping("/send_email")
    public ResultMsg sendEmail(@RequestParam Map<String, Object> params){
        String email = (String) params.get("email");
        String activeCode = Encrypt.randomCode();
        boolean isSuccess = EmailTool.sendEmail(email, activeCode, "1");
        if (!isSuccess) {
            return ResultMsg.error("网络出错，请稍后再试");
        }
        SessionTool.getSession().setAttribute("activeCode", activeCode);
        return ResultMsg.ok("发送成功");
    }

    @PostMapping("activate_email")
    public ResultMsg activateEmail(@RequestParam Map<String, Object> params){
        String activeCode = (String) params.get("activeCode");
        String code = (String) SessionTool.getSession().getAttribute("activeCode");
        if (!code.equals(activeCode.toLowerCase())) {
            return ResultMsg.error("激活码错误");
        }
        User user = SessionTool.getUser();
        user.setActivate("1");
        try {
            userService.updateById(user);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultMsg.error("系统出错，请联系管理员");
        }
        SessionTool.setUser(user);
        return ResultMsg.ok("激活成功");
    }

}
